package com.example.sourcecodelearning.modules.designpattern.template;

import com.example.framework.redis.core.util.RedisUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * @author yuzhenxin
 * @date 2023/8/1
 */
@Slf4j
public abstract class SmsTemplate {

    private static final String SMS_CODE_PREFIX = "sms:code:";

    public void sendMsg(String mobile) throws Exception {
        log.info("检查用户【{}】一分钟内是否发送过短信", mobile);
        if (checkUserReceiveInOneMinute(mobile)) {
            throw new Exception("请等待1分钟后重试");
        }
        String code = genCode();
        if (manufacturer(mobile, code)) {
            log.info("短信厂商发送短信成功，mobile: {}, code: {}", mobile, code);
            save2redis(mobile, code);
        }
    }

    /**
     * 模板方法，由不同的厂商来实现发送短信到手机上
     *
     * @param mobile 手机号
     * @param code   验证码
     * @return 是否发送成功
     */
    protected abstract boolean manufacturer(String mobile, String code);

    /**
     * 检查1分钟内该手机号是否接收过验证码，1分钟内接收过就不能在发送验证码
     *
     * @param mobile 手机号
     * @return 1分钟内该手机号是否接受过验证码
     */
    protected boolean checkUserReceiveInOneMinute(String mobile) {
        return RedisUtils.hasKey(SMS_CODE_PREFIX + mobile);
    }

    /**
     * 生成6位验证码
     *
     * @return 6位验证码
     */
    protected String genCode() {
        return "123456";
    }

    /**
     * 将手机号+验证码存进redis中，给登录接口做校验用
     *
     * @param mobile 手机号
     * @param code   验证码
     */
    protected void save2redis(String mobile, String code) {
        RedisUtils.set(SMS_CODE_PREFIX + mobile, code, 60, TimeUnit.SECONDS);
    }

}
